/*自身对应的.h文件*/
#include "drv_mipi_lcd.h"

/*程序内部对应的.h文件*/
#include "log.h"

/*外部库对应的.h文件*/

/*系统.h文件*/
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>		//open需要的头文件
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>				//write
#include <sys/types.h>
#include <sys/mman.h>			//mmap  内存映射相关函数库
#include <stdlib.h>				//malloc free 动态内存申请和释放函数头文件
#include <string.h>
#include <linux/fb.h>
#include <sys/ioctl.h>

static int g_fd = 0;
static unsigned int *g_fb_mem  = NULL;	//设置显存的位数为32位

typedef struct
{
	struct fb_var_screeninfo var;
	struct fb_fix_screeninfo fix;
}hdmi_param_t;

hdmi_param_t g_hdmi_param = {0};

/***************************************************************
 * Name:	 drv_mipi_lcd_size()
 * Input : void
 * Output: width宽度 height高度
 * Return: 0成功 <0失败
 * Author: hwl
 * Revise: V1.0
 * Description: 获取lcd分辨率
 ***************************************************************/
int drv_mipi_lcd_size(uint16_t *width, uint16_t *heigh)
{
	if(g_fd != 0)
	{
		*width = g_hdmi_param.var.width;
		*heigh = g_hdmi_param.var.height;
		return 0;
	}
	else
	{
		return -1;
	}
}

/***************************************************************
 * Name:	 drv_mipi_lcd_init()
 * Input : void
 * Output: void
 * Return: 0成功 <0失败
 * Author: hwl
 * Revise: V1.0
 * Description: lcd设备初始化
 ***************************************************************/
int drv_mipi_lcd_init(void)
{
	unsigned int i;
	int ret;

	/*--------------第一步--------------*/
	g_fd = open("/dev/fb0",O_RDWR);	//打开framebuffer设备
	if(g_fd == -1){
		LOG_ERROR("open mipi_lcd");
		return -1;
	}
	/*--------------第二步--------------*/

	//获取屏幕的可变参数
	ioctl(g_fd, FBIOGET_VSCREENINFO, &g_hdmi_param.var);
	//获取屏幕的固定参数
	ioctl(g_fd, FBIOGET_FSCREENINFO, &g_hdmi_param.fix);

	//打印分辨率
	LOG_DEBUG("mipi_lcd width= %d height= %d\r\n", g_hdmi_param.var.xres, g_hdmi_param.var.yres);

	/*--------------第三步--------------*/
	g_fb_mem = (unsigned int *)mmap(NULL,
																	g_hdmi_param.var.xres*g_hdmi_param.var.yres*4,	//获取显存，映射内存
																	PROT_READ |  PROT_WRITE, MAP_SHARED, g_fd, 0);

	if(g_fb_mem == MAP_FAILED){
		perror("Mmap mipi_lcd");
		return -1;
	}

	memset(g_fb_mem, 0xff, g_hdmi_param.var.xres*g_hdmi_param.var.yres*4);	//清屏
	sleep(1);
	return 0;
}

/***************************************************************
 * Name:	 drv_mipi_lcd_restore()
 * Input : void
 * Output: void
 * Return: void
 * Author: hwl
 * Revise: V1.0
 * Description: lcd设备注销
 ***************************************************************/
void drv_mipi_lcd_restore(void)
{
	if(g_fb_mem != NULL)
	{
		//映射后的地址，通过mmap返回的值
		munmap(g_fb_mem, g_hdmi_param.var.xres*g_hdmi_param.var.yres*4);
	}

	if(g_fd > 0)
	{
		close(g_fd);	//关闭fb0设备文件
	}
}

/***************************************************************
 * Name:	 drv_mipi_lcd_fill()
 * Input : act_x、act_y开始坐标 end_x、end_y结束坐标 color填充的数据
 * Output: void
 * Return: void
 * Author: hwl
 * Revise: V1.0
 * Description: lcd显示填充
 ***************************************************************/
void drv_mipi_lcd_fill(	const uint16_t act_x, const uint16_t act_y,
												const uint16_t end_x, const uint16_t end_y,
												const uint32_t *color)
{
	uint32_t color_num = 0;

	for(int i = act_y; i <= end_y; i++)
	{
		for(int j = act_x; j <= end_x; j++)
		{
			//更新这个点的显存
			g_fb_mem[i * g_hdmi_param.var.xres + j] = color[color_num];
			color_num++;
		}
	}
}